#!/usr/bin/env python
#
# Copyright 2009 Jonathan Perkins

import datetime
import logging
from google.appengine.api import users
from google.appengine.ext import webapp

import cards
import data


def _CheckedAttr(check):
  if check:
    return 'checked'
  return ''


def _GeneratePage(add, sets):
  add('<html><head>\n'
      '  <link rel=stylesheet type="text/css" href="static/main.css">\n'
      '  <script type="text/javascript" src="static/set_editor.js"></script>\n'
      '<title>Dominion Card Selector - Set Editor</title></head><body>\n'
      '<form name=input action=/set_editor method=post>\n'
      '<table id=sets><tbody>\n')
  for set_index, set in enumerate(sets):
    if not set:
      continue
    add('  <tr id=set%(set_index)d><td>Set Name:\n'
        '    <input name=set%(set_index)d_n value="%(set_name)s"/>\n'
        '    &nbsp;\n'
        '    <input type=button onclick=AddCard(%(set_index)d)\n'
        '        value="Add Card">\n'
        '      &nbsp;\n'
        '    <input type=button onclick=RemoveSet(%(set_index)d)\n'
        '        value="Remove Set"/>\n'
        '    <table border=1 id=set%(set_index)d_cards next_card=%(set_size)d\n'
        '        class=card_input>\n'
        % {'set_index': set_index, 'set_name': set[0],
           'set_size': len(set) - 1})
    add('      <tr>\n'
        '        <th rowspan=2 valign=bottom\n'
        '            style=min-width:15em>Card Name</th>\n'
        '        <th rowspan=2 valign=bottom style=min-width:3.5em>Cost</th>\n'
        '        <th colspan=7>Type</th><th colspan=3>Plus</th>\n'
        '        <th rowspan=2>Remove Card</th>\n'
        '      </tr>\n'
        '      <tr>\n'
        '        <th>Attack</th><th>Action</th><th>Defense</th>\n'
        '        <th>Duration</th><th>Reaction</th><th>Treasure</th>\n'
        '        <th>Victory</th><th>Actions</th><th>Buys</th><th>Cards</th>\n'
        '      </tr>\n')
    for card_index, card_info in enumerate(set[1:]):
      card = cards.CustomCard(card_info, True)
      id = 'card%d_%d' % (set_index, card_index)
      card_args = {'set_index': set_index, 'card_index': card_index, 'id': id,
                   'name': card.name,
                   'ta': _CheckedAttr(card.Is(cards.ACTION)),
                   'tb': _CheckedAttr(card.Is(cards.ATTACK)),
                   'td': _CheckedAttr(card.Is(cards.DEFENSE)),
                   'te': _CheckedAttr(card.Is(cards.DURATION)),
                   'tr': _CheckedAttr(card.Is(cards.REACTION)),
                   'tt': _CheckedAttr(card.Is(cards.TREASURE)),
                   'tv': _CheckedAttr(card.Is(cards.VICTORY)),
                   'pa': _CheckedAttr(card.IsPlus(cards.PLUS_ACTION)),
                   'pb': _CheckedAttr(card.IsPlus(cards.PLUS_BUY)),
                   'pc': _CheckedAttr(card.IsPlus(cards.PLUS_CARD)),
                  }
      add('      <tr id=%(id)s>\n'
          '        <td><input class=full_width name=%(id)s_n\n'
          '            value="%(name)s"/></td>\n'
          '        <td><select class=full_width name=%(id)s_c>\n'
          % card_args)
      for x in range(0, 15) + [99]:
        if x == card.cost:
          add('          <option value=%d selected>%d</option>\n' % (x, x))
        else:
          add('          <option value=%d>%d</option>\n' % (x, x))
      add('        </select></td>\n'
          '        <td><input type=checkbox name=%(id)s_ta %(ta)s/></td>\n'
          '        <td><input type=checkbox name=%(id)s_tb %(tb)s/></td>\n'
          '        <td><input type=checkbox name=%(id)s_td %(td)s/></td>\n'
          '        <td><input type=checkbox name=%(id)s_te %(te)s/></td>\n'
          '        <td><input type=checkbox name=%(id)s_tr %(tr)s/></td>\n'
          '        <td><input type=checkbox name=%(id)s_tt %(tt)s/></td>\n'
          '        <td><input type=checkbox name=%(id)s_tv %(tv)s/></td>\n'
          '        <td><input type=checkbox name=%(id)s_pa %(pa)s/></td>\n'
          '        <td><input type=checkbox name=%(id)s_pb %(pb)s/></td>\n'
          '        <td><input type=checkbox name=%(id)s_pc %(pc)s/></td>\n'
          '        <td><input type=button\n'
          '            onclick=RemoveCard(%(set_index)d,%(card_index)d)\n'
          '            value="Remove"/></td>\n'
          '      </tr>\n'
          % card_args)

    add('    </table>\n'
        '    <br>\n'
        '  </td></tr>\n')
  add('  <tr><td>\n'
      '      <input type=button onclick=AddSet() value="Add Set"/>\n'
      '      &nbsp;\n'
      '      <input type=submit name=button_save value="Save Changes"/>\n'
      '      &nbsp;\n'
      '      <input type=submit name=button_discard value="Discard Changes"/>\n'
      '  </td></tr>\n'
      '</tbody></table>\n'
      '</form>\n'
      '</body></html>\n')


class SetEditor(webapp.RequestHandler):

  def get(self):
    user = users.get_current_user()
    if not user:
      self.redirect('/')

    settings = data.Settings.get_by_key_name(user.user_id())
    if settings:
      sets = [settings.set0,
              settings.set1,
              settings.set2,
              settings.set3,
              settings.set4,
              settings.set5,
              settings.set6,
              settings.set7,
              settings.set8,
              settings.set9,
             ]
      logging.info('Loaded sets: ' + str(sets))
    else:
      sets = [[]] * 10
    _GeneratePage(self.response.out.write, sets)

  def post(self):
    logging.info('Post vars: ' + str(self.request.postvars))
    if 'button_save' in self.request.postvars:
      user = users.get_current_user()
      if not user:
        self.redirect('/')

      settings = data.Settings.get_by_key_name(user.user_id())
      if not settings:
        settings = data.Settings(key_name=user.user_id(), email=user.email())

      sets = {}
      for key, value in self.request.postvars.iteritems():
        if key.startswith('set'):
          set_index, initial = key[3:].split('_')
          set_index = int(set_index)
          if initial == 'n':
            if set_index not in sets:
              sets[set_index] = {}
            sets[set_index]['name'] = value.replace('"', '\'')
        elif key.startswith('card'):
          set_index, card_index, initial = key[4:].split('_')
          set_index = int(set_index)
          card_index = int(card_index)
          main_initial = initial[0]
          if len(initial) > 1:
            sub_initial = initial[1]

          if set_index not in sets:
            sets[set_index] = {}
          if card_index not in sets[set_index]:
            sets[set_index][card_index] = cards.Card(
                'Card ' + str(card_index), True, 0, (), ())
          card = sets[set_index][card_index]

          if main_initial == 'n':
            card.name = value
          elif main_initial == 'c':
            card.cost = int(value)
          elif main_initial == 't':
            card.type_mask |= cards.TYPES[sub_initial].mask
          elif main_initial == 'p':
            card.plus_mask |= cards.PLUSES[sub_initial].mask

      stored_sets = [[]] * 10
      for set_index, set_key in enumerate(sorted(sets.keys())):
        set_dict = sets[set_key]
        set_list = [set_dict['name']]
        del set_dict['name']
        for card_index in sorted(set_dict.keys())[:100]:
          card = set_dict[card_index]
          set_list.append('%d|%d|%d|%s' % (card.cost, card.type_mask,
                                           card.plus_mask, card.name))
        stored_sets[set_index] = set_list

      logging.info('Parsed sets: ' + str(stored_sets))

      settings.last_access = datetime.datetime.now()
      settings.set0 = stored_sets[0]
      settings.set1 = stored_sets[1]
      settings.set2 = stored_sets[2]
      settings.set3 = stored_sets[3]
      settings.set4 = stored_sets[4]
      settings.set5 = stored_sets[5]
      settings.set6 = stored_sets[6]
      settings.set7 = stored_sets[7]
      settings.set8 = stored_sets[8]
      settings.set9 = stored_sets[9]

      settings.put()

    self.redirect('/')
